"""
状态校验器 - 动态状态校验
"""
from typing import Optional, List, Dict, Any
from motor.motor_asyncio import AsyncIOMotorDatabase
from bson import ObjectId

from app.core.state_cache import state_cache
from app.utils.state_utils import get_state_code_by_name_keywords


class StateValidator:
    """状态校验器"""
    
    def __init__(self, db: AsyncIOMotorDatabase):
        self.db = db
    
    async def validate_state_code(self, module_type: str, code: str) -> bool:
        """
        验证状态代码是否有效
        
        Args:
            module_type: 模块类型
            code: 状态代码（会自动转换为大写进行匹配）
            
        Returns:
            bool: 是否有效
        """
        try:
            # 统一转换为大写进行比较（因为状态代码在数据库中存储为大写）
            code_upper = code.upper() if code else code
            
            # 使用缓存获取模块状态（强制刷新以确保最新数据）
            states = await state_cache.get_module_states(self.db, module_type, force_refresh=False)
            
            # 检查状态代码是否存在且启用
            # StateResponse 是 Pydantic 模型，使用属性访问而不是字典访问
            for state in states:
                state_code = state.code if hasattr(state, "code") else (state.get("code") if isinstance(state, dict) else None)
                state_enabled = state.is_enabled if hasattr(state, "is_enabled") else (state.get("is_enabled", False) if isinstance(state, dict) else False)
                # 统一转换为大写进行比较
                state_code_upper = state_code.upper() if state_code else state_code
                if state_code_upper == code_upper and state_enabled:
                    return True
            
            # 如果第一次验证失败，强制刷新缓存后再试一次
            # 这样可以处理状态刚被创建但缓存未更新的情况
            states = await state_cache.get_module_states(self.db, module_type, force_refresh=True)
            for state in states:
                state_code = state.code if hasattr(state, "code") else (state.get("code") if isinstance(state, dict) else None)
                state_enabled = state.is_enabled if hasattr(state, "is_enabled") else (state.get("is_enabled", False) if isinstance(state, dict) else False)
                # 统一转换为大写进行比较
                state_code_upper = state_code.upper() if state_code else state_code
                if state_code_upper == code_upper and state_enabled:
                    return True
            
            # 兼容性处理：对于任务模块，如果 code 是 review，也检查 in_review
            if module_type == "task" and code_upper == "REVIEW":
                for state in states:
                    state_code = state.code if hasattr(state, "code") else (state.get("code") if isinstance(state, dict) else None)
                    state_enabled = state.is_enabled if hasattr(state, "is_enabled") else (state.get("is_enabled", False) if isinstance(state, dict) else False)
                    state_code_upper = state_code.upper() if state_code else state_code
                    if state_code_upper == "IN_REVIEW" and state_enabled:
                        return True
            
            return False
        except Exception as e:
            # 记录错误但不抛出异常
            import logging
            logging.error(f"状态验证失败: {str(e)}")
            return False
    
    async def validate_state_codes(self, module_type: str, codes: List[str]) -> Dict[str, bool]:
        """
        批量验证状态代码
        
        Args:
            module_type: 模块类型
            codes: 状态代码列表
            
        Returns:
            Dict[str, bool]: 代码验证结果映射
        """
        results = {}
        
        try:
            # 使用缓存获取模块状态
            states = await state_cache.get_module_states(self.db, module_type)
            valid_codes = set()
            for state in states:
                state_code = state.code if hasattr(state, "code") else (state.get("code") if isinstance(state, dict) else None)
                state_enabled = state.is_enabled if hasattr(state, "is_enabled") else (state.get("is_enabled", False) if isinstance(state, dict) else False)
                if state_code and state_enabled:
                    # 统一转换为大写存储
                    valid_codes.add(state_code.upper() if state_code else state_code)
            
            for code in codes:
                # 统一转换为大写进行比较
                code_upper = code.upper() if code else code
                results[code] = code_upper in valid_codes
                
        except Exception:
            # 出错时全部标记为无效
            for code in codes:
                results[code] = False
        
        return results
    
    async def get_valid_state_codes(self, module_type: str) -> List[str]:
        """
        获取模块的所有有效状态代码
        
        Args:
            module_type: 模块类型
            
        Returns:
            List[str]: 有效状态代码列表
        """
        try:
            states = await state_cache.get_module_states(self.db, module_type)
            valid_codes = []
            for state in states:
                state_code = state.code if hasattr(state, "code") else (state.get("code") if isinstance(state, dict) else None)
                state_enabled = state.is_enabled if hasattr(state, "is_enabled") else (state.get("is_enabled", False) if isinstance(state, dict) else False)
                if state_code and state_enabled:
                    valid_codes.append(state_code)
            return valid_codes
        except Exception:
            return []
    
    async def get_default_state_code(self, module_type: str) -> Optional[str]:
        """
        获取模块的默认状态代码
        
        Args:
            module_type: 模块类型
            
        Returns:
            Optional[str]: 默认状态代码
        """
        try:
            default_state = await state_cache.get_default_state(self.db, module_type)
            if default_state:
                if hasattr(default_state, 'code'):
                    return default_state.code
                elif isinstance(default_state, dict):
                    return default_state.get("code")
            return None
        except Exception:
            return None
    
    async def validate_state_transition(
        self, 
        module_type: str, 
        from_code: str, 
        to_code: str
    ) -> bool:
        """
        验证状态转换是否允许
        
        Args:
            module_type: 模块类型
            from_code: 源状态代码（会自动转换为大写）
            to_code: 目标状态代码（会自动转换为大写）
            
        Returns:
            bool: 是否允许转换
        """
        # 统一转换为大写
        from_code_upper = from_code.upper() if from_code else from_code
        to_code_upper = to_code.upper() if to_code else to_code
        
        # 基础验证：目标状态必须有效
        if not await self.validate_state_code(module_type, to_code_upper):
            return False
        
        # 如果源状态为空，允许设置为任何有效状态
        if not from_code_upper:
            return True
        
        # 源状态也必须有效
        if not await self.validate_state_code(module_type, from_code_upper):
            return False
        
        # 如果源状态和目标状态相同，允许转换（虽然通常不会发生）
        if from_code_upper == to_code_upper:
            return True
        
        # TODO: 这里可以添加更复杂的状态转换规则
        # 目前允许所有有效状态之间的转换
        return True
    
    async def get_state_info(self, module_type: str, code: str) -> Optional[Dict[str, Any]]:
        """
        获取状态详细信息
        
        Args:
            module_type: 模块类型
            code: 状态代码（会自动转换为大写进行匹配）
            
        Returns:
            Optional[Dict[str, Any]]: 状态信息
        """
        try:
            # 统一转换为大写进行匹配
            code_upper = code.upper() if code else code
            state = await state_cache.get_state_by_code(self.db, module_type, code_upper)
            if state:
                # 转换为字典格式
                if hasattr(state, 'model_dump'):
                    return state.model_dump()
                elif hasattr(state, 'dict'):
                    return state.dict()
                elif isinstance(state, dict):
                    return state
                else:
                    return {
                        "id": str(state.id) if hasattr(state, 'id') else None,
                        "name": state.name if hasattr(state, 'name') else None,
                        "code": state.code if hasattr(state, 'code') else None,
                        "module_type": state.module_type if hasattr(state, 'module_type') else None,
                        "description": state.description if hasattr(state, 'description') else None,
                        "color": state.color if hasattr(state, 'color') else None,
                        "icon": state.icon if hasattr(state, 'icon') else None,
                        "sort_order": state.sort_order if hasattr(state, 'sort_order') else 0,
                        "is_enabled": state.is_enabled if hasattr(state, 'is_enabled') else True,
                        "is_visible": state.is_visible if hasattr(state, 'is_visible') else True,
                        "is_default": state.is_default if hasattr(state, 'is_default') else False,
                    }
            return None
        except Exception as e:
            import logging
            logging.error(f"获取状态信息失败: {str(e)}")
            return None
    
    async def get_state_code_by_name_keywords(self, module_type: str, keywords: List[str]) -> Optional[str]:
        """
        根据状态名称关键词获取状态代码
        
        Args:
            module_type: 模块类型
            keywords: 关键词列表
            
        Returns:
            Optional[str]: 状态代码
        """
        return await get_state_code_by_name_keywords(self.db, module_type, keywords)


def get_state_validator(db: AsyncIOMotorDatabase) -> StateValidator:
    """
    获取状态校验器实例
    每次都创建新实例，确保使用正确的数据库连接
    """
    return StateValidator(db)